package socketmvc.core.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import socketmvc.core.context.IContext;
import socketmvc.core.util.xpath.FastPathMatcher;
import socketmvc.core.util.xpath.PathMatcher;
import socketmvc.core.packets.basic.IPacket;

import java.util.ArrayList;
import java.util.List;

public class AntPathFilterChain implements IFilterChain{
    private final Logger logger = LoggerFactory.getLogger(AntPathFilterChain.class);

    private final List<IFilter> additionalFilters;
    private final int size;
    private int currentPosition;
    private final PathMatcher pathMatcher = new FastPathMatcher();

    public AntPathFilterChain(List<IFilter> additionalFilters) {
        if (additionalFilters == null){
            this.additionalFilters = List.of(new CommandDispatcherFilter()) ;
        }else {
            this.additionalFilters = new ArrayList<>(additionalFilters) ;
            this.additionalFilters.add(new CommandDispatcherFilter());
        }
        this.size = this.additionalFilters.size();
        this.currentPosition = 0;
    }

    @Override
    public void doFilter(IContext context, Object other) {
        IFilter nextFilter = null;
        if (this.currentPosition != this.size) {
            ++this.currentPosition;
            nextFilter = this.additionalFilters.get(this.currentPosition - 1);
        } else {
            if (logger.isDebugEnabled()){
                logger.debug("Filter已全部执行完毕！");
            }
        }
        if (nextFilter != null){
            IPacket packet = context.getPacket();
            if (packet != null){
                String cmd = context.getPacket().getCommand();
                String path = nextFilter.path();
                if (pathMatcher.match(cmd,path)){
                    if (logger.isDebugEnabled()){
                        logger.debug("Command[ {} ]进入[ Filter:{},FilterPath:{} ]",cmd, nextFilter.getClass().getName(),path);
                    }
                    nextFilter.doFilter(context, other, this);
                }else {
                    this.doFilter(context,other);
                }
                return;
            }
            nextFilter.doFilter(context, other, this);
        }
    }


}
